﻿/**
 * 25-Line ActionScript Contest Entry
 * 
 * Project: Tree generator v2
 * Author:  Edgars Simsons http://edzis.wordpress.com simsons.edgars{in}gmail.com
 * Date:    15.01.2009.  
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
 
// 3 free lines! Alter the parameters of the following lines or remove them.
// Do not substitute other code for the three lines in this section
[SWF(width=800, height=800, backgroundColor=0xDBD3AE, frameRate=30)]
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
// 25 lines begins here!

var rootObj			:Object;
var rootRotation	:int = 0;

var main:Shape = addChild(new Shape()) as Shape;
main.transform.matrix = new Matrix(-1, 0, 0, -1, Math.round(stage.stageWidth / 2), stage.stageHeight - 0);

stage.addEventListener(Event.ENTER_FRAME, redraw);
stage.addEventListener(MouseEvent.CLICK, doStart);
doStart();

function redraw(e:Event = null):void  {
	main.graphics.clear();
	rootRotation+=3;
	updateLine(rootObj, new Vector3D(0, 1, 0));
}

function doStart(e:Event = null):void  {rootObj = {level:1, i:0, age:int(0), posRandom:1, maxage:200, rotationZ:90, maxlength:(stage.stageHeight < stage.stageWidth)? stage.stageHeight*4.5 : stage.stageWidth*4.5, parentObj:{rotationY:0, rotationZ:90, posRandom:1, length:0} };}

function updateLine(thisObj:Object, sumVector:Vector3D):void {
	var configObj:Object = {maxlength: (thisObj.maxlength == undefined && thisObj.parentObj.maxlength != undefined)? Math.round(thisObj.parentObj.maxlength * 0.9 * (1 - thisObj.posRandom * 0.4)) : false, rotationY: (thisObj.rotationY == undefined)? (thisObj.parentObj.rotationY + Math.round( Math.random() * 360)) % 360 : false, rotationZ: (thisObj.rotationZ == undefined)? thisObj.parentObj.rotationZ + Math.round( 35 + Math.random() * 15) * (Math.round(Math.random()) * 2 - 1) : false, age: (thisObj.age < thisObj.maxage)? thisObj.age+1 : thisObj.age, length: (thisObj.maxlength == undefined)? 0 : (thisObj.maxlength * Math.sin(thisObj.age/thisObj.maxage * (Math.PI/2))) };
	for (var itemName:String in configObj) { if(itemName == "age" || itemName == "length" || (thisObj[itemName] == undefined && configObj[itemName] != false)) thisObj[itemName] = configObj[itemName] };
	
	var currentVector:Vector3D = new Vector3D(Point.polar(Point.polar(1, thisObj.rotationZ * Math.PI / 180).x*thisObj.length/10, (thisObj.rotationY + rootRotation) * Math.PI / 180).x, Point.polar(1, thisObj.rotationZ * Math.PI / 180).y*thisObj.length/10, Point.polar(Point.polar(1, thisObj.rotationZ * Math.PI / 180).x, (thisObj.rotationY + rootRotation) * Math.PI / 180).y*thisObj.length/10 );
	var parentVector:Vector3D = new Vector3D(Point.polar(Point.polar(1, thisObj.parentObj.rotationZ * Math.PI / 180).x*(thisObj.parentObj.length/10 * thisObj.posRandom), (thisObj.parentObj.rotationY + rootRotation) * Math.PI / 180).x, Point.polar(1, thisObj.parentObj.rotationZ * Math.PI / 180).y*(thisObj.parentObj.length/10 * thisObj.posRandom), Point.polar(Point.polar(1, thisObj.parentObj.rotationZ * Math.PI / 180).x, (thisObj.parentObj.rotationY + rootRotation) * Math.PI / 180).y*(thisObj.parentObj.length/10 * thisObj.posRandom) );

	parentVector.incrementBy(sumVector);
	currentVector.incrementBy(parentVector);
	
	main.graphics.moveTo( parentVector.x, parentVector.y );
	main.graphics.lineStyle(thisObj.length / (80 + thisObj.i * 10), 0x3E2809 );
	main.graphics.lineTo( currentVector.x, currentVector.y );

	if (thisObj.age > thisObj.maxage / 8 && thisObj.length > 30 && thisObj.level < 6) {
		if (thisObj.child0 == null) for (var i:int = (thisObj.level < 3)? 5-i:2; i >= 0; i--) { thisObj["child" + i] = {parentObj:thisObj, level:thisObj.level+1, i:i, age:0, posRandom: (i == 0) ? 1 : 1 - i * 0.1 - Math.round(Math.random() * 2) / 10, maxage: Math.round(thisObj.maxage * (0.99 + Math.random() * 0.2))  }};
		for (var j:int = 0; thisObj["child"+j] != null; j++) updateLine(thisObj["child"+j], parentVector);
	}
}
// 25 lines ends here!